Skip to content

feat(spec,parse): add repeatable clause groups - #1321

Merged
jdx merged 12 commits into
feat/complete-sigil-argsfrom
feat/spec-clause-interpreter
Aug 28, 2026
Merged

feat(spec,parse): add repeatable clause groups#1321
jdx merged 12 commits into
feat/complete-sigil-argsfrom
feat/spec-clause-interpreter

Conversation

@jdx

@jdx jdx commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • add separator-delimited repeatable clause declarations
  • group each clause instance independently in interpreted parse output
  • restart flags, positional state, and automatic trailing-value behavior at clause boundaries
  • protect literal separators after explicit double dash
  • add clause-aware completion, documentation, fixtures, and validation

Stack

Test plan

  • cargo test -p usage-conformance --test clause --test reference
  • cargo test -p usage-cli complete_word_clause
  • mise run lint

AI-assisted — Tool: Codex; model: OpenAI/GPT-5; version: unavailable.


Note

Medium Risk
Touches core argv parsing, completion heuristics, and relationship validation; behavior changes are broad but gated behind new spec syntax and covered by conformance tests.

Overview
Introduces clauses: repeatable positional groups separated by a token (e.g. :::), with each instance stored in ParseOutput.clauses instead of overwriting like restart_token.

Spec & parser: New clause KDL node (min_usage_version 6.6), mutually exclusive with top-level args, restart_token, and sigil args inside the clause. Parsing treats the separator as syntax (even after double_dash="automatic"), resets positional/flag state per instance, honors explicit -- for literal separators, skips env/defaults for clause args, and validates required/relationship rules per instance. Positional grammar routes through active_args() so clause inner args drive the cursor.

Completion & docs: Shell completion treats a clause separator like a restart (first inner arg choices, flags re-enabled across instances). Adds reference docs, example spec, docs model field, and MissingClauseArg errors.

Tests: Conformance suite for multi-instance values, double-dash behavior, negatives, KDL round-trip, and per-instance relationships; CLI completion tests for separator and default-subcommand paths.

Reviewed by Cursor Bugbot for commit af6ee72. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 63a43af2-c3db-41d1-a8e1-cfeaba2d5656

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread lib/src/parse.rs
Comment thread lib/src/parse.rs
Comment thread lib/src/parse.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from afb02b9 to a3dcdce Compare August 25, 2026 17:41
Comment thread lib/src/parse.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from a3dcdce to bde9cf0 Compare August 25, 2026 17:53
Comment thread cli/src/cli/complete_word.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from bde9cf0 to 77c2d44 Compare August 25, 2026 18:00
Comment thread lib/src/parse.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from 77c2d44 to 664f277 Compare August 25, 2026 18:14
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from 5055214 to 14f6fc6 Compare August 25, 2026 18:17
Comment thread cli/src/cli/complete_word.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from 14f6fc6 to ea0bc3a Compare August 25, 2026 18:26
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch 2 times, most recently from 936196b to 8b07e40 Compare August 25, 2026 18:47
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
markdown ▁█ 339,188,544 → 341,629,318 +0.72% 29.28 → 29.45ms +0.58%
startup █▁ 910,943 → 908,006 -0.32% 0.85 → 0.92ms +7.15%

No instruction-count regression above 1%.

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

Shadow comparison

Parsing mise use -g node@20 against a shadow of mise's committed spec.
Reported, not gated: the shadow grows as the derive learns to express more, so
what to watch is the ratio rather than either column.

framework stripped binary, bytes
usage 1328960
bpaf 2493280
clap 3101832
framework instructions, cold parse vs usage
usage 8477
clap 6315570 745x
bpaf 21909031 2584x
                                              min       p01       p10    median
usage-rs: argv -> struct                      447       453       455       458  ns
clap: build tree + parse -> struct         516386    518460    521135    525456  ns
bpaf: build parser + parse -> struct      1565160   1565160   1583664   1605641  ns

usage: argv -> struct                             450 ns      0.45 µs
clap: build tree + parse -> struct             537716 ns    537.72 µs
clap: parse -> struct, tree reused              24044 ns     24.04 µs
clap: build tree only                          330667 ns    330.67 µs

af6ee72adaaa vs 3d27ebdb6f9d · measured on the runner, not pushed to the history.

@jdx
jdx force-pushed the feat/spec-clause-interpreter branch 2 times, most recently from 6b00bd5 to b908b50 Compare August 25, 2026 20:19
Comment thread lib/src/parse.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from b908b50 to 1b61021 Compare August 25, 2026 20:39
Comment thread lib/src/parse.rs
Comment thread lib/src/parse.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from d74267e to f824fa6 Compare August 25, 2026 20:59
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from f824fa6 to 715e8a5 Compare August 25, 2026 21:12
Comment thread lib/src/parse.rs
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch 2 times, most recently from 00988bb to 7db6c6c Compare August 27, 2026 13:04
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from 7db6c6c to a9175f9 Compare August 28, 2026 12:35
@jdx
jdx force-pushed the feat/spec-clause-interpreter branch from a9175f9 to 3100bf7 Compare August 28, 2026 13:11

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3100bf7. Configure here.

Comment thread lib/src/parse.rs
@jdx
jdx merged commit 6e61f0d into main Aug 28, 2026
12 checks passed
@jdx
jdx deleted the feat/spec-clause-interpreter branch August 28, 2026 14:14
jdx added a commit that referenced this pull request Aug 28, 2026
## Summary
- add clause tables and boundary events to the zero-allocation argv
parser
- support typed Vec<T> clause fields through usage derive
- add equivalent Go parser, spec-lowering, and generated-table support
- extend the shared corpus so interpreted Rust, compiled Rust, and Go
agree
- report clause addition, removal, and separator changes as breaking in
usage diff

## Stack
- Depends on #1321

## Test plan
- mise run test
- mise run lint
- mise run render
- mise run gen-shadow
- cd go && go test ./...

*AI-assisted — Tool: Codex; model: OpenAI/GPT-5; version: unavailable.*

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes core positional parsing and completion cursor rules across
Rust and Go; spec clause changes are intentionally breaking, but
behavior is covered by new corpus and conformance tests.
> 
> **Overview**
> Adds **repeatable clause** support: a command can declare one
separator-delimited positional group (e.g. `:::`) whose inner arguments
reset on each boundary instead of overwriting the previous instance.
> 
> The **argv parser** gains `Command.clause`, a `ClauseSeparator` event,
and positional binding through the clause’s inner args (including after
restart tokens and when automatic `--` stops flags). **Completions**,
**help/usage**, and **spec emission** now treat clause positionals like
ordinary args, with usage showing a repeatable `[separator …]…` pattern.
> 
> **Derive** supports `#[usage(clause, separator = "…")]` on `Vec<T>`
(`T: Args`) with partial/build/apply wiring; **Go** mirrors the same
parser, help, spec lowering, and generated `Parse` structs.
**Conformance** and a new corpus section expect a `clauses` map of
per-instance arg bindings; **usage diff** marks clause
add/remove/separator changes as breaking.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
8703b56. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant